package net.seninp.fdata.runner;

import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.FormatFlagsConversionMismatchException;
import java.util.Formatter;
import java.util.List;
import java.util.Locale;
import net.seninp.fdata.data.Cell;
import net.seninp.fdata.data.FDataFactory;
import net.seninp.fdata.data.Measurement;
import net.seninp.fdata.data.Measurements;
import net.seninp.fdata.data.MeasurementsGrid;
import net.seninp.fdata.data.Year;

/**
 * Take CSV -> read into measurement instances -> partition by regions -> get discords.
 *
 * @author psenin
 *
 */
public class GetDiscords {

  private static final String inName = "data//sepo_yft_catch_S8_S9.CSV";

  private static final String[] fisheries = { "8", "9" };

  private static final Integer gridXSize = 10;
  private static final Integer gridYSize = 10;

  private static final String CELL_TEMPLATE = "        ";

  /**
   * Main executable.
   *
   * @param args None used here.
   * @throws IOException
   */
  public static void main(String[] args) throws IOException {

    // read the data
    //
    System.out.println("Reading data ... ");
    Measurements measurements = FDataFactory.getMeasuremenets(inName);

    // put up some stats
    //
    System.out.println("Read " + measurements.size() + " instances from " + inName);

    System.out.println("  max latd " + measurements.getMaxLatd() + ", min "
        + measurements.getMinLatd());
    System.out.println("  max lond " + measurements.getMaxLond() + ", min "
        + measurements.getMinLond());

    // and some more stats with grid
    //
    System.out.println("\n  Grid by measurement counts:");
    MeasurementsGrid grid = FDataFactory.mapToGridByWindow(measurements, gridXSize, gridYSize);

    int totalCount = 0;
    for (int i = 0; i < grid.sizeX(); i++) {
      for (int j = 0; j < grid.sizeY(); j++) {
        System.out.print(cellSize2String(grid.getCell(i, j)));
        totalCount += grid.getCell(i, j).measurementsCount();
      }
      System.out.println();
    }
    System.out.println("Total: " + totalCount);

    System.out.println("\n  Grid by years of measurements 'complete(partial)':");
    for (int i = 0; i < grid.sizeX(); i++) {
      for (int j = 0; j < grid.sizeY(); j++) {
        System.out.print(cellYears2String(grid.getCell(i, j)));
      }
      System.out.println();
    }

    System.out.println("\n  Cells and years ... ");
    for (int i = 0; i < grid.sizeX(); i++) {
      for (int j = 0; j < grid.sizeY(); j++) {
        Cell c = grid.getCell(i, j);
        if (c.hasCompleteYears()) {
          System.out.println("Cell [" + i + "][" + j + "]:\n" + cell2CompleteYearsSeries(c));
        }
      }
    }

  }

  private static String cell2CompleteYearsSeries(Cell c) {
    StringBuilder sb = new StringBuilder();
    Formatter fmt = new Formatter(sb, Locale.US);

    fmt.format("Cell boundaries: Lond [%f,%f], ", c.getMinLond(), c.getMaxLond());
    fmt.format(" Latd [%f,%f]\n", c.getMinLatd(), c.getMaxLatd());

    for (String fishery : fisheries) {
      fmt.format("  fishery: %s:\n", fishery);

      for (Integer y : c.getFullYears(fishery)) {
        fmt.format("   %d\n", y);
        fmt.format("     days: %s\n", arr2String(c.getEffort(fishery, y)));
        fmt.format("     tons: %s\n", arr2String(c.getCatch(fishery, y)));
        fmt.format("     effectiveness, tn/day: %s\n", arr2String(c.getEffectiveness(fishery, y)));
      }

    }

    return sb.toString();
  }

  private static String arr2String(double[] data) {
    NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
    DecimalFormat df = (DecimalFormat) nf;
    df.applyPattern("###.0000");

    StringBuilder sb = new StringBuilder();
    sb.append("(");
    for (int i = 0; i < data.length - 1; i++) {
      sb.append(df.format(data[i])).append(", ");
    }
    return sb.append(df.format(data[data.length - 1])).append(")").toString();
  }

  private static String cellYears2String(Cell cell) {
    String fc = String.valueOf(cell.fullYearsCount());
    String pc = String.valueOf(cell.partialYearsCount());
    String res = fc + "(" + pc + ")";
    return CELL_TEMPLATE.substring(0, CELL_TEMPLATE.length() - res.length()).concat(res);
  }

  private static String cellSize2String(Cell cell) {
    String s = String.valueOf(cell.measurementsCount());
    return CELL_TEMPLATE.substring(0, CELL_TEMPLATE.length() - s.length()).concat(s);
  }

}
